<?php

class Template {

    private $themeDir = NULL; //模板目录
    private $tplDir = null; //编译后的php文件存放目录

    private $themeExt = ".html";
    private $tplExt = ".tpl.php"; //编译后的文件后缀

    private $pattern = array(
        "/\{template\s+(.+?)\}/ie",
        "/\<\!\-\-\{if\s+(.+?)\}\-\-\>/s",
        "/\<\!\-\-\{elseif(.+?)\}\-\-\>/s",
        "/\<\!\-\-\{else\}\-\-\>/s",
        "/\<\!\-\-\{loop\s+(\S+)\s+(\S+)\}\-\-\>/s",
        "/\<\!\-\-\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}\-\-\>/s",
        "/\<\!\-\-\{\/if\}\-\->/s",
        "/\<\!\-\-\{\/loop\}\-\->/s",
        "/\{\\$(.+?)\}/is",
        "/\{eval\s+(.+?)\}/is",
        "/\{echo\s+(.+?)\}/is"

    );

    private $replacement = array(
        '$this->inc_file("$1")',
        "<?php if( \\1 ) { ?>\n",
        "<?php }elseif( \\1 ) { ?>\n",
        "<?php }else{ ?>\n",
        "<?php foreach( \\1 as \\2 ) { ?>\n",
        "<?php foreach( \\1 as \\2 => \\3 ) { ?>\n",
        "<?php } ?>\n",
        "<?php } ?>\n",
        "<?php echo $\\1; ?>",
        "<?php \\1 ; ?>\n",
        "<?php echo \\1; ?>"
    );

    // 设置模板,编译目录
    public function init( $themeDir = NULL, $tplDir = NULL ) {
        $this->themeDir = $themeDir;
        $this->tplDir = $tplDir;
        mkdirs( $this->tplDir );
    }

    /**
     * 返回编译后文件
     * @param tplFile     要编译的模板文件
     * @param refresh     是否重新编译模板
     */
    public function display( $file, $refresh = true ) {

        if ( empty( $file ) ) die( "Template \"{$file}\" not exist !" );

        // 编译文件
        $tplFile = $this->tplDir . md6( $file ) . $this->tplExt;

        // 模板文件
        $themeFile = is_file( $file ) ? $file : ( $this->themeDir . $file . $this->themeExt );

        // 模板内容
        $Content = file_get_contents( $themeFile );

        if ( !$Content ) die( "Template \"{$themeFile}\" not exist !" );

        // 检查是否需要重新编译
        if ( @filemtime( $themeFile ) > @filemtime( $tplFile ) || !file_exists( $tplFile ) || $refresh ) {
            //对读取出来的内容进行编译
            $compileContent = $this->compile_file( $Content );
            file_put_contents( $tplFile, $compileContent );
            chmod( $tplFile, 0666 );
        }

        return $tplFile;
    }

    // 编译文件函数
    private function compile_file( $content = null ) {
        $content = preg_replace( $this->pattern, $this->replacement, $content );
        $content = preg_replace( "/\?\>(\s+)\<\?php/s", "", $content );
        return $content;
    }

    // 解析包含文件
    private function inc_file( $filename ) {
        $file = $this->tplDir . md6( $filename ) . $this->tplExt;
        $tplFile = $this->themeDir . $filename . $this->themeExt;

        if ( @filemtime( $tplFile ) > @filemtime( $file ) || !file_exists( $file ) ) {
            $tplContent = file_get_contents( $tplFile );
            $compileContent = $this->compile_file( $tplContent );
            file_put_contents( $file, $compileContent );
            chmod( $file, 0666 );
        }

        $file = str_replace( "\\", "/", $file );
        return "<?php include \"{$file}\"; ?>";
    }
}